package lesson2.example1;

import com.sun.tools.javac.code.*;
import com.sun.tools.javac.file.JavacFileManager;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.tree.JCTree.*;
import com.sun.tools.javac.tree.TreeMaker;
import com.sun.tools.javac.util.*;

public class TestTreeMaker {

	static Names names;
	static TreeMaker F;

	public static void main(String[] args) {

		Context context = new Context();
		JavacFileManager.preRegister(context);
		F = TreeMaker.instance(context);
		names = Names.instance(context);

		// private String name;
		JCModifiers mods = F.Modifiers(Flags.PRIVATE);
		Name tn = names.fromString("String");
		JCIdent type = F.Ident(tn);
		Name name = names.fromString("name");
		JCVariableDecl jcv = F.VarDef(mods, name, type, null);
		
		/*
		 public String getName() {
				return name;
		 }
		*/
		JCMethodDecl jcm = makeGetterMethodDecl(F,jcv);

		// 类中的有序列表
		ListBuffer<JCTree> defs = new ListBuffer<JCTree>();
		defs.append(jcv);
		defs.append(jcm);
		
		
		// public class TestGetSetAnnotation
		JCModifiers mods1 = F.Modifiers(Flags.PUBLIC);
		Name name1 = names.fromString("TestGetSetAnnotation");
		List<JCTypeParameter> typarams = List.nil();
		List<JCExpression> implementing = List.nil();
		JCClassDecl jcc = F.ClassDef(mods1, name1, typarams, null, implementing, defs.toList());

		
		// 编译单元的有序列表
		ListBuffer<JCTree> defsx = new ListBuffer<JCTree>();
		defsx.add(jcc);
		List<JCAnnotation> packageAnnotations = List.nil();

		// package lesson2
		JCIdent ifr = F.Ident(names.fromString("lesson2"));
		JCExpression pid = ifr;
		JCCompilationUnit toplevel = F.TopLevel(packageAnnotations, pid, defsx.toList());

		System.out.println(toplevel.toString());
	}
	
	private static JCMethodDecl makeGetterMethodDecl(TreeMaker F,JCVariableDecl jcVariableDecl) {

		ListBuffer<JCTree.JCStatement> statements = new ListBuffer<>();
		JCIdent jci = F.Ident(names.fromString("name"));
		JCReturn jcr = F.Return(jci);
		statements.append(jcr);
		JCTree.JCBlock body = F.Block(0, statements.toList());

		return F.MethodDef(
					F.Modifiers(Flags.PUBLIC), 
					getNewMethodName(jcVariableDecl.getName()),
					jcVariableDecl.vartype, 
					List.<JCTypeParameter>nil(), 
					List.<JCVariableDecl>nil(),
					List.<JCExpression>nil(), 
					body, 
					null
				);
	}
	
	private static Name getNewMethodName(Name name) {
		String s = name.toString();
		String mn = "get" + s.substring(0, 1).toUpperCase() + s.substring(1, name.length());
		return names.fromString(mn);
	}
	
}
